#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
// #include <cjson/cJSON.h>
#include "./cJSON.h"

#include "./ui/ui.h"

static const char *getenv_default(const char *name, const char *dflt)
{
    return getenv(name) ?: dflt;
}

#if LV_USE_LINUX_FBDEV
static void lv_linux_disp_init(void)
{
    const char *device = getenv_default("LV_LINUX_FBDEV_DEVICE", "/dev/fb0");
    lv_display_t *disp = lv_linux_fbdev_create();

    lv_linux_fbdev_set_file(disp, device);
}
#elif LV_USE_SDL
static void lv_linux_disp_init(void)
{
    const int width = atoi(getenv("LV_SDL_VIDEO_WIDTH") ?: "800");
    const int height = atoi(getenv("LV_SDL_VIDEO_HEIGHT") ?: "480");

    lv_sdl_window_create(width, height);
}
#else
#error Unsupported configuration
#endif

void my_chinese_font(char *text)
{
    // 1.创建中文字体
    lv_font_t *font = lv_freetype_font_create("/home/gec/simkai.ttf", // 👍加载字库文件
                                              LV_FREETYPE_FONT_RENDER_MODE_BITMAP,
                                              24,
                                              LV_FREETYPE_FONT_STYLE_NORMAL);

    // 2.创建中文字体样式
    static lv_style_t style;
    lv_style_init(&style);                                 // 初始化样式
    lv_style_set_text_font(&style, font);                  // 设置中文字体样式
    lv_style_set_text_align(&style, LV_TEXT_ALIGN_CENTER); // 字体居中显示

    lv_obj_t *label = lv_label_create(lv_screen_active());
    lv_obj_add_style(label, &style, 0); // 👍给标签添加中文字体
    lv_label_set_text(label, text);
    lv_obj_center(label);
}
//定义一个锁
pthread_mutex_t mutex;
struct weather
{
    char tianqi[10];
    lv_obj_t * ui_Imageweather;
};

void image_weather(struct weather *w)
{
    if(strcmp(w->tianqi, "多云") == 0)
        lv_image_set_src(w->ui_Imageweather, &ui_img_1772208564);
    else if(strcmp(w->tianqi, "大雨") == 0||strcmp(w->tianqi, "暴雨") == 0)
        lv_image_set_src(w->ui_Imageweather, &ui_img_31364788);
    else if(strcmp(w->tianqi, "小雨") == 0||strcmp(w->tianqi, "中雨") == 0)
        lv_image_set_src(w->ui_Imageweather, &ui_img_972225589);
    else if(strcmp(w->tianqi, "晴") == 0)
        lv_image_set_src(w->ui_Imageweather, &ui_img_1931249499);
    else if(strcmp(w->tianqi, "阴") == 0)
        lv_image_set_src(w->ui_Imageweather, &ui_img_610615781);
    else if(strcmp(w->tianqi, "阵雨")  == 0)
        lv_image_set_src(w->ui_Imageweather,  &ui_img_1842525092);
}
void *weather_data(void *arg)
{
        //创建通信对象
    int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
    if(tcp_socket == -1)
    {
        perror("socket");
        return -1;
    }
    //链接服务器
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(80);
    server_addr.sin_addr.s_addr = inet_addr("116.253.29.34");
    if(connect(tcp_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
    {
        perror("connect");
        return -1;
    }
    //请求数据报
    char *req = "GET /api/weather/city/101280101 HTTP/1.1\r\nHost:t.weather.itboy.net\r\nConnection: close\r\n\r\n";
    //发送数据报
    int n = write(tcp_socket, req, strlen(req));
    if(n == -1)
    {
        perror("write");
        return -1;
    }
    //接收数据报
    char buf[16384] = {0};  // 增大缓冲区
    int total_len = 0;      // 记录已读取的总字节数
    int max_len = sizeof(buf) - 1;  // 预留一个字节给结束符
    
    while (1) 
    {
        // 从当前位置继续读取，最多读取缓冲区剩余空间
        int n = read(tcp_socket, buf + total_len, max_len - total_len);
        if(n == -1)
        {
            perror("read");
            close(tcp_socket);
            return -1;
        }
        else if(n == 0)
        {
            // n=0表示服务器已关闭连接，数据读取完毕
            break;
        }
        total_len += n;  // 累加已读取字节数
    }
    buf[total_len] = '\0';
    //切割数据
    char *p = strstr(buf, "{");
    //关闭套接字
    close(tcp_socket);
    //用json库来解析天气
    cJSON *obj = cJSON_Parse(p);
    if(obj == NULL)
    {
        printf("解析失败\n");
        return -1;
    }
    char *date_time = cJSON_GetObjectItem(obj, "time")->valuestring;
    char date[20];
    strncpy(date, date_time, 10);
    date[10] = '\0';
    char real_date[20];
    sprintf(real_date,"日期：%s", date);
    //上锁
    pthread_mutex_lock(&mutex);
    lv_label_set_text(ui_Labelcurrentdate, real_date);
    //解锁
    pthread_mutex_unlock(&mutex);
    cJSON *data = cJSON_GetObjectItem(obj, "data");
    cJSON *forecast = cJSON_GetObjectItem(data, "forecast");
    //计算数组大小
    int size = cJSON_GetArraySize(forecast);
    //遍历数组
    for(int i = 0; i < 6; i++)
    {
        //获取数组中的元素
        cJSON *tmp_obj=cJSON_GetArrayItem(forecast, i);
        //获取日期
        char *dateday = cJSON_GetObjectItem(tmp_obj, "date")->valuestring;
        char realdateday[20];
        sprintf(realdateday, "%s日", dateday);
        // printf("日期：%s\n", realdateday);
        //获取周
        char *week = cJSON_GetObjectItem(tmp_obj, "week")->valuestring;
        // printf("周：%s\n",week);
        //获取天气
        char *weather = cJSON_GetObjectItem(tmp_obj, "type")->valuestring;
        // printf("天气：%s\n", weather);
        //获取最高温度
        char *high = cJSON_GetObjectItem(tmp_obj, "high")->valuestring;
        char *hightransfer = high+7;
        char hightransfer2[20];
        strncpy(hightransfer2, hightransfer, 2);
        char realhigh[20];
        sprintf(realhigh, "%s°C", hightransfer2);
        // printf("最高温度：%s\n",realhigh);
        //获取最低温度
        char *low = cJSON_GetObjectItem(tmp_obj, "low")->valuestring;
        char *lowtransfer = low+7;
        char lowtransfer2[20];
        strncpy(lowtransfer2, lowtransfer, 2);
        char reallow[20];
        sprintf(reallow, "%s°C", lowtransfer2);
        // printf("最低温度：%s\n",reallow);
        struct weather w;
        strcpy(w.tianqi, weather);
        //照片刷新
        if(i==0)
        {
            w.ui_Imageweather=ui_Imageweather1;
            //上锁
            pthread_mutex_lock(&mutex);
            lv_label_set_text_fmt(ui_Labelweek1, "%s", week);
            lv_label_set_text_fmt(ui_Labelweather1, "%s", weather);
            lv_label_set_text_fmt(ui_Labeltmpmax1, "%s", realhigh);
            lv_label_set_text_fmt(ui_Labeltmpmin1, "%s", reallow);
            image_weather(&w);
            //解锁
            pthread_mutex_unlock(&mutex);
            
        }
        else if(i==1)
        {
            w.ui_Imageweather=ui_Imageweather2;
            //上锁
            pthread_mutex_lock(&mutex);
            lv_label_set_text_fmt(ui_Labelday2, "%s", realdateday);
            lv_label_set_text_fmt(ui_Labelweek2, "%s", week);
            lv_label_set_text_fmt(ui_Labelweather2, "%s", weather);
            lv_label_set_text_fmt(ui_Labeltmpmax2, "%s", realhigh);
            lv_label_set_text_fmt(ui_Labeltmpmin2, "%s", reallow);
            image_weather(&w);
            //解锁
            pthread_mutex_unlock(&mutex);
        }
        else if(i==2)
        {
            w.ui_Imageweather=ui_Imageweather3;
            //上锁
            pthread_mutex_lock(&mutex);
            lv_label_set_text_fmt(ui_Labelday3, "%s", realdateday);
            lv_label_set_text_fmt(ui_Labelweek3, "%s", week);
            lv_label_set_text_fmt(ui_Labelweather3, "%s", weather);
            lv_label_set_text_fmt(ui_Labeltmpmax3, "%s", realhigh);
            lv_label_set_text_fmt(ui_Labeltmpmin3, "%s", reallow);
            image_weather(&w);
            //解锁
            pthread_mutex_unlock(&mutex);
        }
        else if(i==3)
        {
            w.ui_Imageweather=ui_Imageweather4;
            //上锁
            pthread_mutex_lock(&mutex);
            lv_label_set_text_fmt(ui_Labelday4, "%s", realdateday);
            lv_label_set_text_fmt(ui_Labelweek4, "%s", week);
            lv_label_set_text_fmt(ui_Labelweather4, "%s", weather);
            lv_label_set_text_fmt(ui_Labeltmpmax4, "%s", realhigh);
            lv_label_set_text_fmt(ui_Labeltmpmin4, "%s", reallow);
            image_weather(&w);
            //解锁
            pthread_mutex_unlock(&mutex);
        }
        else if(i==4)
        {
            w.ui_Imageweather=ui_Imageweather5;
            //上锁
            pthread_mutex_lock(&mutex);
            lv_label_set_text_fmt(ui_Labelday5, "%s", realdateday);
            lv_label_set_text_fmt(ui_Labelweek5, "%s", week);
            lv_label_set_text_fmt(ui_Labelweather5, "%s", weather);
            lv_label_set_text_fmt(ui_Labeltmpmax5, "%s", realhigh);
            lv_label_set_text_fmt(ui_Labeltmpmin5, "%s", reallow);
            image_weather(&w);
            //解锁
            pthread_mutex_unlock(&mutex);
        }
        else if(i==5)
        {
            w.ui_Imageweather=ui_Imageweather6;
            //上锁
            pthread_mutex_lock(&mutex);
            lv_label_set_text_fmt(ui_Labelday6, "%s", realdateday);
            lv_label_set_text_fmt(ui_Labelweek6, "%s", week);
            lv_label_set_text_fmt(ui_Labelweather6, "%s", weather);
            lv_label_set_text_fmt(ui_Labeltmpmax6, "%s", realhigh);
            lv_label_set_text_fmt(ui_Labeltmpmin6, "%s", reallow);
            image_weather(&w);
            //解锁
            pthread_mutex_unlock(&mutex);
        }       
    }
}
int main(void)
{
    lv_init();
    /*Linux display device init*/
    lv_linux_disp_init();

#if LV_USE_SDL
    // init input device
    lv_sdl_mouse_create();
    lv_sdl_keyboard_create();
    lv_sdl_mousewheel_create();
#endif

#if LV_USE_LINUX_FBDEV
    // 创建输入设备
    lv_indev_t *touch = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event0");
    // 校准输入设备屏幕坐标
    // lv_evdev_set_calibration(touch, 0, 0, 1024, 600); // 黑色边框的屏幕
    lv_evdev_set_calibration(touch, 0, 0, 800, 480);  // 蓝色边框的屏幕
#endif
    //初始化锁
    pthread_mutex_init(&mutex, NULL);
    ui_init();
    
    //创建一个线程
    pthread_t tid;
    pthread_create(&tid, NULL, weather_data, NULL);
    /*Handle LVGL tasks*/
    while (1)
    {
        //上锁
        pthread_mutex_lock(&mutex);
        lv_timer_handler();
        //解锁
        pthread_mutex_unlock(&mutex);
        usleep(5000);
    }
    return 0;
}
